package com.platform.utils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 日期处理
 *
 * @author lipengjun
 * @email 939961241@qq.com
 * @date 2016年12月21日 下午12:53:33
 */
public class DateUtils {
    // 日志
    private static final Logger logger = Logger.getLogger(DateUtils.class);

    /**
     * 时间格式(yyyy-MM-dd)
     */
    public final static String DATE_PATTERN = "yyyy-MM-dd";
    /**
     * 无分隔符日期格式 "yyyyMMddHHmmssSSS"
     */
    public static String DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS_SSS = "yyyyMMddHHmmssSSS";
    
    public static String DATE_TIME_PATTERN_YYYY_MM_DD_SSS = "yyyyMMddSSS";

    public static String DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS = "yyyyMMddHHmmss";

    public final static Date FOREVER_DATE;
    
    private static String timePattern = "HH:mm";
    public static String dateTimePattern = "yyyy-MM-dd HH:mm:ss";
    private static String monthPattern = "yyyy年MM月";
    
	/** 用于计算某个月份中的最后一天 */
	private static final int[] dayArray = new int[] { 31, 28, 31, 30, 31, 30,
		31, 31, 30, 31, 30, 31 };

    
    static {
	    Calendar c=Calendar.getInstance();
	    c.set(Calendar.YEAR, 2999);
	    FOREVER_DATE = c.getTime();
    }
    
    /**
     * 时间格式(yyyy-MM-dd HH:mm:ss)
     */
    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    // 日期转换格式数组
    public static String[][] regularExp = new String[][]{

            // 默认格式
            {"\\d{4}-((([0][1,3-9]|[1][0-2]|[1-9])-([0-2]\\d|[3][0,1]|[1-9]))|((02|2)-(([1-9])|[0-2]\\d)))\\s+([0,1]\\d|[2][0-3]|\\d):([0-5]\\d|\\d):([0-5]\\d|\\d)",
                    DATE_TIME_PATTERN},
            // 仅日期格式 年月日
            {"\\d{4}-((([0][1,3-9]|[1][0-2]|[1-9])-([0-2]\\d|[3][0,1]|[1-9]))|((02|2)-(([1-9])|[0-2]\\d)))",
                    DATE_PATTERN},
            //  带毫秒格式
            {"\\d{4}((([0][1,3-9]|[1][0-2]|[1-9])([0-2]\\d|[3][0,1]|[1-9]))|((02|2)(([1-9])|[0-2]\\d)))([0,1]\\d|[2][0-3])([0-5]\\d|\\d)([0-5]\\d|\\d)\\d{1,3}",
                    DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS_SSS}
    };

    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    public static String timeToStr(Long time, String pattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        if (time.toString().length() < 13) {
            time = time * 1000L;
        }
        Date date = new Date(time);
        String value = dateFormat.format(date);
        return value;
    }

    public static long strToTime(String timeStr) {
        Date time = strToDate(timeStr);
        return time.getTime() / 1000;
    }


    /**
     * 转换为时间类型格式
     *
     * @param strDate 日期
     * @return
     */
    public static Date strToDate(String strDate) {
        try {
            String strType = getDateFormat(strDate);
            SimpleDateFormat sf = new SimpleDateFormat(strType);
            return new Date((sf.parse(strDate).getTime()));
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 根据传入的日期格式字符串，获取日期的格式
     *
     * @return 秒
     */
    public static String getDateFormat(String date_str) {
        String style = null;
        if (StringUtils.isEmpty(date_str)) {
            return null;
        }
        boolean b = false;
        for (int i = 0; i < regularExp.length; i++) {
            b = date_str.matches(regularExp[i][0]);
            if (b) {
                style = regularExp[i][1];
            }
        }
        if (StringUtils.isEmpty(style)) {
            logger.info("date_str:" + date_str);
            logger.info("日期格式获取出错，未识别的日期格式");
        }
        return style;
    }

    /**
     * 将字符串类型的转换成Date类型
     *
     * @param dateStr
     *            字符串类型的日期 yyyy-MM-dd
     * @return Date类型的日期
     * @throws ParseException
     */
    public static Date convertStringToDate(String dateStr) {
        // 返回的日期
        Date resultDate = null;
        try {
            // 日期格式转换
            SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN);
            resultDate = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return resultDate;
    }

	/**
	 * 【取得默认的日期的格式】<br>
	 * 默认格式为：yyyy-MM-dd
	 * 
	 * @return 在本类中定义的日期格式
	 */
    public static synchronized String getDatePattern() {
        return DATE_PATTERN;
    }

    /**
     * 获取月份
     * @param aDate
     * @return
     */
    public static String getMonth(Date aDate){
        SimpleDateFormat df = null;
        String returnValue = "";

        if (aDate != null) {
            df = new SimpleDateFormat(monthPattern);
            returnValue = df.format(aDate);
        }
        return (returnValue);
    }
    
	/**
	 * 【取得默认的日期、时间格式】<br>
	 * 默认格式为：yyyy-MM-dd HH:mm:ss
	 * 
	 * @return 在本类中定义的日期、时间格式
	 */
    public static synchronized String getDateTimePattern() {
        return dateTimePattern;
    }

	/**
	 * 【将指定日期转化为系统默认格式的字符串】<br>
	 * 
	 * @param 将要转换的日期
	 * @return 按默认格式转换后的日期
	 */
    public static synchronized final String getDate(Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";

        if (aDate != null) {
            df = new SimpleDateFormat(DATE_PATTERN);
            returnValue = df.format(aDate);
        }

        return (returnValue);
    }
    /**
     * 【将指定日期转化为指定格式的字符串】<br>
     * 
     * @param 将要转换的日期
     * @return 按默认格式转换后的日期
     */
    public static synchronized final String getDate(Date aDate,String datePattern) {
    	SimpleDateFormat df = null;
    	String returnValue = "";
    	
    	if (aDate != null) {
    		df = new SimpleDateFormat(datePattern);
    		returnValue = df.format(aDate);
    	}
    	
    	return (returnValue);
    }

    public static Date getYestDay(){
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_YEAR, -1);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.MILLISECOND,   0);
    	return calendar.getTime();
    }
	/**
	 * 昨天
	 * @return
	 */
	public static Calendar getYesterdayCal(){
		Calendar cal =Calendar.getInstance(); 
		cal.add(Calendar.DAY_OF_MONTH, -1);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.MILLISECOND,   0);
		return cal;
	}
	
	/**
	 * 前天
	 * @return
	 */
	public static Calendar getBeforeYesterdayCal(){
		Calendar cal =Calendar.getInstance(); 
		cal.add(Calendar.DAY_OF_MONTH, -2);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.MILLISECOND,   0);
		return cal;
	}   
	/**
	 * 【将字符串按指定的格式转成日期】<br>
	 * convertStringToDate("yyyy-MM-dd HH:mm:ss", "2007-01-01 01:01:59")
	 * 
	 * @param 日期格式
	 * @param 待转换的字符串
	 * @return 转换成的日期
	 * @see java.text.SimpleDateFormat
	 * @throws ParseException
	 */
    public static synchronized final Date convertStringToDate(String aMask, String strDate)
      throws ParseException {
        SimpleDateFormat df = null;
        Date date = null;
        df = new SimpleDateFormat(aMask);
        try {
            date = df.parse(strDate);
        } catch (ParseException pe) {
            //log.error("ParseException: ",pe);
            throw new ParseException(pe.getMessage(), pe.getErrorOffset());
        }

        return (date);
    }

	/**
	 * 【取得指定指定日期中的时间部分】<br>
	 * ex:getTimeNow(new Date()) : "14:34"
	 * 
	 * @param theTime
	 *            the current time
	 * @return the current date/time
	 */
    public static synchronized String getTimeNow(Date theTime) {
        return getDateTime(timePattern, theTime);
    }

	/**
	 * 【取得当前日期】
	 * 
	 * @return the current date
	 * @throws ParseException
	 */
    public static synchronized Calendar getToday() throws ParseException {
		Calendar cal =Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND,   0);
        return cal;
    }
    
    /**
     * This method returns the current date in the format: MM/dd/yyyy
     * 
     * @return the input date
     * @throws ParseException
     */
    public static synchronized Calendar getCalendar(Date date) throws ParseException{
    	SimpleDateFormat df = new SimpleDateFormat(DATE_PATTERN);

        // This seems like quite a hack (date -> string -> date),
        // but it works ;-)
        String todayAsString = df.format(date);
        Calendar cal = new GregorianCalendar();
        cal.setTime(convertStringToDate(todayAsString));
        return cal;
    }

	/**
	 * 【取得指定日期的日期时间字符串格式】<br>
	 * ex:getDateTime("yyyy-MM-dd HH:mm:ss",new Date()) : 2007-06-04 14:37:59
	 * 
	 * @param 日期时间格式
	 * @param 时间
	 * @return 指定格式的时间值字符串
	 * 
	 * @see java.text.SimpleDateFormat
	 */
    public static synchronized final String getDateTime(String aMask, Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";

        if (aDate == null) {
        	logger.error("aDate is null!");
        } else {
            df = new SimpleDateFormat(aMask);
            returnValue = df.format(aDate);
        }

        return (returnValue);
    }

	/**
	 * 【取得指定日期的日期时间字符串格式】<br>
	 * ex:getDateTime(new Date()) : 2007-06-04 14:37:59
	 * 
	 * @param 日期时间格式
	 * @param 时间
	 * @return 指定格式的时间值字符串
	 * 
	 * @see java.text.SimpleDateFormat
	 */
    public static synchronized final String getDateTime(Date aDate) {
    	return	getDateTime(dateTimePattern,aDate);
    }

	/**
	 * 【取得当前日期的日期、时间字符串格式】<br>
	 * getDateTimeNow(): 2007-06-04 14:37:59
	 * 
	 * @param 日期时间格式
	 * @param 时间
	 * @return 指定格式的时间值字符串
	 * 
	 * @see java.text.SimpleDateFormat
	 */
    public static synchronized final String getDateTimeNow() {
    	return	getDateTime(dateTimePattern,new Date());
	}
    public static synchronized final String getDateTimeNow(String dateTimePattern) {
    	return	getDateTime(dateTimePattern,new Date());
	}
	/**
	 * 【将日期转成指定格式的字符串】<br>
	 * convertDateToString(new Date()) : "2007-06-04"
	 * 
	 * @param aDate
	 *            A date to convert
	 * @return a string representation of the date
	 */
    public static synchronized final String convertDateToString(Date aDate) {
        return getDateTime(DATE_PATTERN, aDate);
    }

	/**
	 * 【返回指定格式的当前日期、时间值】<br>
	 * 调用方法：getDateFormatStr("yyyy-MM-dd HH:mm:ss"): 2007-01-01 01:01:01;
	 * 
	 * @param formart
	 * @return
	 */
	public static synchronized String getDateFormatStr(String formart) {
		return new SimpleDateFormat(formart).format(new java.util.Date());
	}

	/**
	 * 
	 * <p>
	 * 【得到指定月的第一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午02:36:57]
	 */
	public static synchronized java.util.Calendar getFirstDayOfMonth(
			java.util.Calendar gc) {
		/**
		 * 详细设计： 1.设置为1号
		 */
		gc.set(GregorianCalendar.DAY_OF_MONTH, 1);
		gc.set(GregorianCalendar.HOUR_OF_DAY, 0);
		gc.set(GregorianCalendar.MINUTE, 0);
		gc.set(GregorianCalendar.SECOND,0);
		return gc;
	}

	/**
	 * 取得指定日期的所处月份的第一天
	 * 
	 * @param date
	 *            指定日期。
	 * @return 指定日期的所处月份的第一天
	 */
	public static synchronized java.util.Date getFirstDayOfMonth(
			java.util.Date date) {
		/**
		 * 详细设计： 1.设置为1号
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.set(Calendar.DAY_OF_MONTH, 1);
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【取得下个月的第一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:03:41]
	 */
	public static synchronized java.util.Calendar getFirstDayOfNextMonth(
			java.util.Calendar gc) {
		/**
		 * 详细设计： 1.调用getNextMonth设置当前时间 2.以1为基础，调用getFirstDayOfMonth
		 */
		gc.setTime(getNextMonth(gc.getTime()));
		gc.setTime(getFirstDayOfMonth(gc.getTime()));
		return gc;
	}

	/**
	 * <p>
	 * 【取得指定日期的下一个月的第一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期。
	 * @return 指定日期的下一个月的第一天
	 * @author:XiangChunKe [2007-8-14 下午03:04:00]
	 */
	public static synchronized java.util.Date getFirstDayOfNextMonth(
			java.util.Date date) {
		/**
		 * 详细设计： 1.调用getNextMonth设置当前时间 2.以1为基础，调用getFirstDayOfMonth
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(getNextMonth(gc.getTime()));
		gc.setTime(getFirstDayOfMonth(gc.getTime()));
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【取得指定日期的下个星期的第一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:04:36]
	 */
	public static synchronized java.util.Calendar getFirstDayOfNextWeek(
			java.util.Calendar gc) {
		/**
		 * 详细设计： 1.调用getNextWeek设置当前时间 2.以1为基础，调用getFirstDayOfWeek
		 */
		gc.setTime(getNextWeek(gc.getTime()));
		gc.setTime(getFirstDayOfWeek(gc.getTime()));
		return gc;
	}

	/**
	 * <p>
	 * 【取得指定日期的下一个星期的第一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的下一个星期的第一天
	 * @author:XiangChunKe [2007-8-14 下午03:05:00]
	 */
	public static synchronized java.util.Date getFirstDayOfNextWeek(
			java.util.Date date) {
		/**
		 * 详细设计： 1.调用getNextWeek设置当前时间 2.以1为基础，调用getFirstDayOfWeek
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(getNextWeek(gc.getTime()));
		gc.setTime(getFirstDayOfWeek(gc.getTime()));
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【取得指定日期的所处星期的第一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:06:17]
	 */
	public static synchronized java.util.Calendar getFirstDayOfWeek(
			java.util.Calendar gc) {
		/**
		 * 详细设计： 1.如果date是星期日，则减0天 2.如果date是星期一，则减1天 3.如果date是星期二，则减2天
		 * 4.如果date是星期三，则减3天 5.如果date是星期四，则减4天 6.如果date是星期五，则减5天
		 * 7.如果date是星期六，则减6天
		 */
		switch (gc.get(Calendar.DAY_OF_WEEK)) {
		case (Calendar.SUNDAY  ):
			gc.add(Calendar.DATE, 0);
			break;
		case (Calendar.MONDAY  ):
			gc.add(Calendar.DATE, -1);
			break;
		case (Calendar.TUESDAY  ):
			gc.add(Calendar.DATE, -2);
			break;
		case (Calendar.WEDNESDAY  ):
			gc.add(Calendar.DATE, -3);
			break;
		case (Calendar.THURSDAY  ):
			gc.add(Calendar.DATE, -4);
			break;
		case (Calendar.FRIDAY  ):
			gc.add(Calendar.DATE, -5);
			break;
		case (Calendar.SATURDAY  ):
			gc.add(Calendar.DATE, -6);
			break;
		}
		return gc;
	}

	/**
	 * <p>
	 * 【取得指定日期的所处星期的第一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的所处星期的第一天
	 * @author:XiangChunKe [2007-8-14 下午03:06:25]
	 */
	public static synchronized java.util.Date getFirstDayOfWeek(
			java.util.Date date) {
		/**
		 * 详细设计： 1.如果date是星期日，则减0天 2.如果date是星期一，则减1天 3.如果date是星期二，则减2天
		 * 4.如果date是星期三，则减3天 5.如果date是星期四，则减4天 6.如果date是星期五，则减5天
		 * 7.如果date是星期六，则减6天
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(Calendar.DAY_OF_WEEK)) {
		case (Calendar.SUNDAY  ):
			gc.add(Calendar.DATE, 0);
			break;
		case (Calendar.MONDAY  ):
			gc.add(Calendar.DATE, -1);
			break;
		case (Calendar.TUESDAY  ):
			gc.add(Calendar.DATE, -2);
			break;
		case (Calendar.WEDNESDAY  ):
			gc.add(Calendar.DATE, -3);
			break;
		case (Calendar.THURSDAY  ):
			gc.add(Calendar.DATE, -4);
			break;
		case (Calendar.FRIDAY  ):
			gc.add(Calendar.DATE, -5);
			break;
		case (Calendar.SATURDAY  ):
			gc.add(Calendar.DATE, -6);
			break;
		}
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【取得指定月份的最后一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param month
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午02:46:34]
	 */
	public static synchronized int getLastDayOfMonth(int month) {
		if (month < 1 || month > 12)
			return -1;
		int retn = 0;
		if (month == 2) {
			if (isLeapYear()) {
				retn = 29;
			} else {
				retn = dayArray[month - 1];
			}
		} else {
			retn = dayArray[month - 1];
		}
		return retn;
	}

	/**
	 * <p>
	 * 【取得指定年、月的最后一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param year
	 * @param month
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:07:24]
	 */
	public static synchronized int getLastDayOfMonth(int year, int month) {
		if (month < 1 || month > 12)
			return -1;
		int retn = 0;
		if (month == 2) {
			if (isLeapYear(year)) {
				retn = 29;
			} else {
				retn = dayArray[month - 1];
			}
		} else {
			retn = dayArray[month - 1];
		}
		return retn;
	}

	/**
	 * 
	 * <p>
	 * 【取得指定日期的所处月份的最后一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午02:37:53]
	 */
	public static synchronized java.util.Calendar getLastDayOfMonth(
			java.util.Calendar gc) {
		/**
		 * 详细设计： 1.如果date在1月，则为31日 2.如果date在2月，则为28日 3.如果date在3月，则为31日
		 * 4.如果date在4月，则为30日 5.如果date在5月，则为31日 6.如果date在6月，则为30日
		 * 7.如果date在7月，则为31日 8.如果date在8月，则为31日 9.如果date在9月，则为30日
		 * 10.如果date在10月，则为31日 11.如果date在11月，则为30日 12.如果date在12月，则为31日
		 * 1.如果date在闰年的2月，则为29日
		 */
		switch (gc.get(Calendar.MONTH)) {
		case 0:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 1:
			gc.set(Calendar.DAY_OF_MONTH, 28);
			break;
		case 2:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 3:
			gc.set(Calendar.DAY_OF_MONTH, 30);
			break;
		case 4:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 5:
			gc.set(Calendar.DAY_OF_MONTH, 30);
			break;
		case 6:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 7:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 8:
			gc.set(Calendar.DAY_OF_MONTH, 30);
			break;
		case 9:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 10:
			gc.set(Calendar.DAY_OF_MONTH, 30);
			break;
		case 11:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		}
		// 检查闰年
		if ((gc.get(Calendar.MONTH) == Calendar.FEBRUARY)
				&& (isLeapYear(gc.get(Calendar.YEAR)))) {
			gc.set(Calendar.DAY_OF_MONTH, 29);
		}
		return gc;
	}

	/**
	 * 取得指定日期的所处月份的最后一天
	 * 
	 * @param date
	 *            指定日期。
	 * @return 指定日期的所处月份的最后一天
	 */
	public static synchronized java.util.Date getLastDayOfMonth(
			java.util.Date date) {
		/**
		 * 详细设计： 1.如果date在1月，则为31日 2.如果date在2月，则为28日 3.如果date在3月，则为31日
		 * 4.如果date在4月，则为30日 5.如果date在5月，则为31日 6.如果date在6月，则为30日
		 * 7.如果date在7月，则为31日 8.如果date在8月，则为31日 9.如果date在9月，则为30日
		 * 10.如果date在10月，则为31日 11.如果date在11月，则为30日 12.如果date在12月，则为31日
		 * 1.如果date在闰年的2月，则为29日
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(Calendar.MONTH)) {
		case 0:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 1:
			gc.set(Calendar.DAY_OF_MONTH, 28);
			break;
		case 2:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 3:
			gc.set(Calendar.DAY_OF_MONTH, 30);
			break;
		case 4:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 5:
			gc.set(Calendar.DAY_OF_MONTH, 30);
			break;
		case 6:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 7:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 8:
			gc.set(Calendar.DAY_OF_MONTH, 30);
			break;
		case 9:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		case 10:
			gc.set(Calendar.DAY_OF_MONTH, 30);
			break;
		case 11:
			gc.set(Calendar.DAY_OF_MONTH, 31);
			break;
		}
		// 检查闰年
		if ((gc.get(Calendar.MONTH) == Calendar.FEBRUARY)
				&& (isLeapYear(gc.get(Calendar.YEAR)))) {
			gc.set(Calendar.DAY_OF_MONTH, 29);
		}
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【取得指定日期的下一个月的最后一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的下一个月的最后一天
	 * @author:XiangChunKe [2007-8-14 下午03:17:16]
	 */
	public static synchronized java.util.Date getLastDayOfNextMonth(
			java.util.Date date) {
		/**
		 * 详细设计： 1.调用getNextMonth设置当前时间 2.以1为基础，调用getLastDayOfMonth
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(getNextMonth(gc.getTime()));
		gc.setTime(getLastDayOfMonth(gc.getTime()));
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【取得指定日期的下一个星期的最后一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的下一个星期的最后一天
	 * @author:XiangChunKe [2007-8-14 下午03:17:40]
	 */
	public static synchronized java.util.Date getLastDayOfNextWeek(
			java.util.Date date) {
		/**
		 * 详细设计： 1.调用getNextWeek设置当前时间 2.以1为基础，调用getLastDayOfWeek
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(getNextWeek(gc.getTime()));
		gc.setTime(getLastDayOfWeek(gc.getTime()));
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【取得指定日期的所处星期的最后一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的所处星期的最后一天
	 * @author:XiangChunKe [2007-8-14 下午03:20:19]
	 */
	public static synchronized java.util.Date getLastDayOfWeek(
			java.util.Date date) {
		/**
		 * 详细设计： 1.如果date是星期日，则加6天 2.如果date是星期一，则加5天 3.如果date是星期二，则加4天
		 * 4.如果date是星期三，则加3天 5.如果date是星期四，则加2天 6.如果date是星期五，则加1天
		 * 7.如果date是星期六，则加0天
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(Calendar.DAY_OF_WEEK)) {
		case (Calendar.SUNDAY  ):
			gc.add(Calendar.DATE, 6);
			break;
		case (Calendar.MONDAY  ):
			gc.add(Calendar.DATE, 5);
			break;
		case (Calendar.TUESDAY  ):
			gc.add(Calendar.DATE, 4);
			break;
		case (Calendar.WEDNESDAY  ):
			gc.add(Calendar.DATE, 3);
			break;
		case (Calendar.THURSDAY  ):
			gc.add(Calendar.DATE, 2);
			break;
		case (Calendar.FRIDAY  ):
			gc.add(Calendar.DATE, 1);
			break;
		case (Calendar.SATURDAY  ):
			gc.add(Calendar.DATE, 0);
			break;
		}
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【取下一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:20:47]
	 */
	public static synchronized java.util.Calendar getNextDay(
			java.util.Calendar gc) {
		/**
		 * 详细设计： 1.指定日期加1天
		 */
		gc.add(Calendar.DATE, 1);
		return gc;
	}

	/**
	 * <p>
	 * 【取得指定日期的下一天】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的下一天
	 * @author:XiangChunKe [2007-8-14 下午03:21:37]
	 */
	public static synchronized java.util.Date getNextDay(java.util.Date date) {
		/**
		 * 详细设计： 1.指定日期加1天
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.DATE, 1);
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【得到下一个月】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：指定日期的月份加1
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:21:59]
	 */
	public static synchronized java.util.Calendar getNextMonth(
			java.util.Calendar gc) {
		/**
		 * 详细设计： 1.指定日期的月份加1
		 */
		gc.add(Calendar.MONTH, 1);
		return gc;
	}

	/**
	 * <p>
	 * 【取得指定日期的下一个月】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：指定日期的月份加1
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的下一个月
	 * @author:XiangChunKe [2007-8-14 下午03:31:16]
	 */
	public static synchronized java.util.Date getNextMonth(java.util.Date date) {
		/**
		 * 详细设计： 1.指定日期的月份加1
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.MONTH, 1);
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【取得指定日期的下一个月】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：指定日期加7天
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:32:13]
	 */
	public static synchronized java.util.Calendar getNextWeek(
			java.util.Calendar gc) {
		/**
		 * 详细设计： 1.指定日期加7天
		 */
		gc.add(Calendar.DATE, 7);
		return gc;
	}

	/**
	 * <p>
	 * 【取得指定日期的下一个星期】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的下一个星期
	 * @author:XiangChunKe [2007-8-14 下午03:33:06]
	 */
	public static synchronized java.util.Date getNextWeek(java.util.Date date) {
		/**
		 * 详细设计： 1.指定日期加7天
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.DATE, 7);
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【得到指定日期的后一个工作日】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：1.如果date是星期五，则加3天<br>
	 * 2.如果date是星期六，则加2天<br>
	 * 3.否则加1天
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:33:26]
	 */
	public static synchronized java.util.Calendar getNextWeekDay(
			java.util.Calendar gc) {
		/**
		 * 详细设计： 1.如果date是星期五，则加3天 2.如果date是星期六，则加2天 3.否则加1天
		 */
		switch (gc.get(Calendar.DAY_OF_WEEK)) {
		case (Calendar.FRIDAY    ):
			gc.add(Calendar.DATE, 3);
			break;
		case (Calendar.SATURDAY    ):
			gc.add(Calendar.DATE, 2);
			break;
		default:
			gc.add(Calendar.DATE, 1);
			break;
		}
		return gc;
	}

	/**
	 * <p>
	 * 【得到指定日期的后一个工作日】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：1.如果date是星期五，则加3天<br>
	 * 2.如果date是星期六，则加2天<br>
	 * 3.否则加1天
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:35:25]
	 */
	public static synchronized java.util.Date getNextWeekDay(java.util.Date date) {
		/**
		 * 详细设计： 1.如果date是星期五，则加3天 2.如果date是星期六，则加2天 3.否则加1天
		 */
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(Calendar.DAY_OF_WEEK)) {
		case (Calendar.FRIDAY    ):
			gc.add(Calendar.DATE, 3);
			break;
		case (Calendar.SATURDAY    ):
			gc.add(Calendar.DATE, 2);
			break;
		default:
			gc.add(Calendar.DATE, 1);
			break;
		}
		return gc.getTime();
	}

	/**
	 * <p>
	 * 【得到指定日期的前一个工作日】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注： 1.如果date是星期日，则减3天<br>
	 * 2.如果date是星期六，则减2天 <br>
	 * 3.否则减1天
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:36:40]
	 */
	public static synchronized java.util.Date getPreviousWeekDay(
			java.util.Calendar gc) {
		{
			/**
			 * 详细设计： 1.如果date是星期日，则减3天 2.如果date是星期六，则减2天 3.否则减1天
			 */
			switch (gc.get(Calendar.DAY_OF_WEEK)) {
			case (Calendar.MONDAY    ):
				gc.add(Calendar.DATE, -3);
				break;
			case (Calendar.SUNDAY    ):
				gc.add(Calendar.DATE, -2);
				break;
			default:
				gc.add(Calendar.DATE, -1);
				break;
			}
			return gc.getTime();
		}
	}

	/**
	 * <p>
	 * 【得到指定日期的前一个工作日】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注： 1.如果date是星期日，则减3天<br>
	 * 2.如果date是星期六，则减2天 <br>
	 * 3.否则减1天
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的前一个工作日
	 * @author:XiangChunKe [2007-8-14 下午03:36:07]
	 */
	public static synchronized java.util.Date getPreviousWeekDay(
			java.util.Date date) {
		{
			/**
			 * 详细设计： 1.如果date是星期日，则减3天 2.如果date是星期六，则减2天 3.否则减1天
			 */
			GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
			gc.setTime(date);
			return getPreviousWeekDay(gc);
			//   switch ( gc.get( Calendar.DAY_OF_WEEK ) )
			//   {
			//    case ( Calendar.MONDAY    ):
			//     gc.add( Calendar.DATE, -3 );
			//     break;
			//    case ( Calendar.SUNDAY    ):
			//     gc.add( Calendar.DATE, -2 );
			//     break;
			//    default:
			//     gc.add( Calendar.DATE, -1 );
			//     break;
			//   }
			//   return gc.getTime();
		}
	}

	public static synchronized boolean isLeapYear() {
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		return isLeapYear(year);
	}

	/**
	 * <p>
	 * 【判断指定日期的年份是否是闰年】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param year
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:07:12]
	 */
	public static synchronized boolean isLeapYear(int year) {
		/**
		 * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年
		 * 3.能被4整除同时能被100整除则不是闰年
		 */
		if ((year % 400) == 0)
			return true;
		else if ((year % 4) == 0) {
			if ((year % 100) == 0)
				return false;
			else
				return true;
		} else
			return false;
	}

	/**
	 * <p>
	 * 【判断指定日期的年份是否是闰年】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param gc
	 * @return
	 * @author:XiangChunKe [2007-8-14 下午03:37:48]
	 */
	public static synchronized boolean isLeapYear(java.util.Calendar gc) {
		/**
		 * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年
		 * 3.能被4整除同时能被100整除则不是闰年
		 */
		int year = gc.get(Calendar.YEAR);
		return isLeapYear(year);
	}

	/**
	 * <p>
	 * 【判断指定日期的年份是否是闰年】
	 * </p>
	 * <p>
	 * 条件：
	 * </p>
	 * <p>
	 * 备注：
	 * </p>
	 * <p>
	 * 例子：
	 * </p>
	 * <p>
	 * 日志：
	 * </p>
	 * 
	 * @param date
	 *            指定日期
	 * @return 是否闰年
	 * @author:XiangChunKe [2007-8-14 下午03:38:09]
	 */
	public static synchronized boolean isLeapYear(java.util.Date date) {
		/**
		 * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年
		 * 3.能被4整除同时能被100整除则不是闰年
		 */
		//  int year = date.getYear();
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		int year = gc.get(Calendar.YEAR);
		return isLeapYear(year);
	}

	public static int month2Month(Date endDate ,Date startDate){
        Calendar   a2   =   Calendar.getInstance(); 
        Calendar   b2   =   Calendar.getInstance(); 
        a2.setTime(startDate); 
        b2.setTime(endDate); 
        int   result   =   (b2.get(Calendar.YEAR)   -   a2.get(Calendar.YEAR))   *   12 
        +   (b2.get(Calendar.MONTH)   -   a2.get(Calendar.MONTH)); 
        return result; 
	}
	
	public static Integer day2Day(Date endDate ,Date startDate){
		long result = endDate.getTime() - startDate.getTime();
		result = result/1000/60/60/24;
		return (int)result; 
	}
	
	/**
	 * 多少天前
	 * @param lastDays
	 * @return
	 */
	public static Date getLastNumberDay(Integer lastDays){
		Calendar cal =Calendar.getInstance(); 
		cal.add(Calendar.DAY_OF_MONTH, -lastDays);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.MILLISECOND,   0);
		return cal.getTime();
	}
	
	public static String getLastNMonth(int n){
		Calendar cal = Calendar.getInstance(); 
		cal.add(Calendar.MONTH, -n);
		return getDate(cal.getTime(),"yyyyMM");
	}
	
    public static void main(String[] args) {
    	
    	String str = "10月14日上午10:35";

    	System.out.println(DateUtils.getDateFormat(str));
        
        
	    Calendar c=Calendar.getInstance();
        System.out.println(DateUtils.format(c.getTime()));
	    c.add(Calendar.DAY_OF_YEAR, 1);
        System.out.println(DateUtils.format(c.getTime()));

    }
}
